/**
 * 
 */
package designpattern.example.pos.barpay.unionall.templet;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

import javax.management.Query;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import designpattern.example.pos.barpay.unionall.BarpayParams;
import designpattern.example.pos.barpay.unionall.entity.PayChannel;
import designpattern.example.pos.barpay.unionall.entity.PayChannelCharacteristic;
import designpattern.example.pos.barpay.unionall.entity.PosGoodsBusinessPayConfig;
import designpattern.example.pos.barpay.unionall.interfaces.ChannelPayInterface;

/**
 *
 *@类名称：ChannelPayTemplate.java
 *@类描述：渠道支付模板方法
 *	1、设计模式:模板模式、适配器模式
 *	2、模板模式：抽象支付过程
 *	3、适配器模式：兼容历史支付渠道的代码
 *@创建人：zhongy
 *@创建时间：2017年9月21日-上午11:26:00
 *@修改备注:
 *@version 
 */
public abstract class ChannelPayTemplate implements ChannelPayInterface,Runnable{
	static Logger log = Logger.getLogger(ChannelPayTemplate.class);
	private CyclicBarrier barr;
	private BarpayParams params;
	/**
	 * 构造函数(子类需要调用父类该构造器)
	 * @param params 支付参数
	 * @param barr	线程屏障
	 */
	public ChannelPayTemplate(BarpayParams params,CyclicBarrier barr){
		this.params = params;
		this.barr = barr;
	}
	/**
	 * 构造函数(需要用于)
	 */
	public ChannelPayTemplate(){
		super();
	}
	
	@Override
	public void run() {
		String className=params.getLogpre();
		try {
			barpay(params);
		} catch (Exception e) {
			log.error("run "+className+" error", e);
		}
		try {
			log.info(className+" is complete!");
			barr.await();
		} catch (InterruptedException e) {
			log.error(className+" await InterruptedException", e);
		} catch (BrokenBarrierException e) {
			log.error(className+" await BrokenBarrierException", e);
		}
		params.setComplete(true);
	}
	
	/**
	 * 
	 *@描述  ：模板二维码支付
	 *@创建人：zhongy
	 *@创建时间：2017年9月24日 下午4:55:43
	 *@修改人：
	 *@修改时间：
	 *@修改描述：
	 *@param params
	 *@throws Exception
	 */
	public void barpay(BarpayParams params) throws Exception{
		/*
		step1、基础参数效验（参数的非空、签名效验）
		step2、调用适配之后的方法方法（异常、超时的时候，取消订单）
		step3、返回值解析
		step3.1、失败；直接返回
		step3.2、成功；a、修改采购商信息；b、更新各个渠道需要的其他参数
		step4、结束请求
		*/
		String logPre=params.getLogpre();
		//step1、基础参数效验（参数的非空）
		if(params==null|| params.getConfig()==null ||StringUtils.isBlank(params.getBarcode())
				||params.getPrice()<0||StringUtils.isBlank(params.getOrderId())||StringUtils.isBlank(params.getPosId())){
			log.info(logPre+"支付参数为空");
			return ;
		}
		//通道支付参数效验
		PosGoodsBusinessPayConfig pgbpc=params.getConfig();
		if(pgbpc==null){
			log.info(logPre+"供应商配置参数不存在");
			return ;
		}
	
		
		if(!checkParams(pgbpc)){
			log.info(logPre+"支付渠道参数为空");
			return ;
		}
		//step2、调用模板支付方法（异常、超时的时候，取消订单）  需要抽象  适用适配器方式进行底层实现
		ChannelPayResult result= barpayAdapter(params);		
		//step3、返回值解析
		//step3.1、失败；直接返回
		if(!result.isIfSuccess()){
			log.info(logPre+"支付失败,paychannelCode="+pgbpc.getPayChannelCode()+",orderId="+params.getOrderId());
			return;
		}
		
		//step3.2、成功；a、修改采购商信息；b、更新各个渠道需要的其他参数
		//讯联特殊处理(根据账户中*，判断是否是支付宝)
		if(pgbpc.getPayChannelCode()==PayChannel.BARPAY_XUNLIAN_ALIPAY || pgbpc.getPayChannelCode()==PayChannel.BARPAY_XUNLIAN_WEIXIN){
			String buyer=result.getBuyer();
			if((StringUtils.isBlank(buyer)?"":buyer).indexOf("*")>-1){//表示是支付宝
				pgbpc.setPayChannelCode(PayChannel.BARPAY_XUNLIAN_ALIPAY);
			}		
		}
		PayChannelCharacteristic pcc= pgbpc.getPcc();//支付渠道特征值

		//采购商信息更新
		//购买人信息更新
		//订单状态更新
		//第三方订单号更新
	
		//支付商户号保存、支付支付交易码保存
		//一般不会出现异常
		
		//支付cmd保存
		
		
		
		//step4、结束请求	
		
		
		
		
	}
	
	

	
	/**
	 * 
	 *@描述  ：目标支付渠道支付(采用适配器模式)
	 *	需要完成的工作
	 *	1、入参：通用入参转化为目标方法的入参；例如：PosGoodsBusinessPayConfig-->GoodsBusinessAlipay
	 *	2、返回值：返回值包装成模板能识别的参数；主要为 isIfSuccess 支付成功;apOrderId 第三方订单号;
	 *	实现流程：
	 *	step1、入参转化
	 *	step2、调用原始方法支付
	 *	step3、返回值转化
	 *	step4、其他处理
	 *@创建人：zhongy
	 *@创建时间：2017年9月24日 下午3:58:02
	 *@修改人：
	 *@修改时间：
	 *@修改描述：
	 *@param params
	 */
	public abstract ChannelPayResult barpayAdapter(BarpayParams params);
	
	

}
